home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / arcers / tar316.zip / STORE.C < prev    next >
Text File  |  1994-07-21  |  7KB  |  290 lines

  1. /* store.c - storying files into (tape) archive
  2.  * This is the part of the Tar program (see file tar.c)
  3.  * Author: T.V.Shaporev
  4.  * Creation date 14 Dec 1990
  5.  */
  6. #include <stdio.h>
  7.  
  8. #include "sysup.h"
  9. #include "nodedef.h"
  10. #include "modern.h"
  11. #include "define.h"
  12.  
  13. char longname[] = "Tar: \'%s\' name too long%s";
  14.  
  15. #ifdef unix
  16. #    ifdef sun
  17. #        ifndef STDDIR
  18. #            define STDDIR
  19. #        endif
  20. #        include <dirent.h>
  21. #        define    DIRENT struct dirent
  22. #        define    namelen(d) strlen((d)->d_name)
  23. #    endif
  24. #    ifdef i386
  25. #        ifndef STDDIR
  26. #            define STDDIR
  27. #        endif
  28. #        include <dirent.h>
  29. #        define    DIRENT struct dirent
  30. #        define    namelen(d) strlen((d)->d_name)
  31. #    else
  32. #        ifdef M_XENIX
  33. #            ifndef STDDIR
  34. #                define STDDIR
  35. #            endif
  36. #            include <sys/ndir.h>
  37. #            define    DIRENT DIR
  38. #            define    namelen(d) ((d)->d_namlen)
  39. #        endif
  40. #    endif
  41. #endif
  42. #ifdef UNIX
  43. #    ifndef STDDIR
  44. #        include <sys/dir.h>
  45. #    endif
  46. #endif
  47.  
  48. #ifdef MSDOS
  49. #    include <string.h>
  50. #    ifdef __TURBOC__
  51. #        include <dir.h>
  52. #    else
  53. #        include <direct.h>
  54. #    endif
  55. #    include <io.h>
  56. #else
  57.     int  strlen();
  58.     char *strcpy(), *strcat(), *strncpy();
  59.     int  open(), read(), close();
  60. #    ifdef RMKDIR
  61.         int rmdir();
  62. #    endif
  63.     long lseek();
  64. #endif
  65.  
  66. #define dotname(n) ((n)[0]=='.' && ((n)[1]=='\0'||((n)[1]=='.'&&(n)[2]=='\0')))
  67.  
  68. void proctl  __ARGS__(( char *, long ));
  69. void procts  __ARGS__(( char *, short, char ));
  70. void prcsum  __ARGS__(( register header * ));
  71. void newhead __ARGS__(( char *, long ));
  72. char *deleft __ARGS__(( char * ));
  73.  
  74. void nullblock(h)
  75. header *h;
  76. {
  77.    register i; for (i=0; i<BLKSIZE/sizeof(int); i++) *((int *)h + i) = 0;
  78. }
  79.  
  80. void proctl(dest, l)
  81. char dest[]; long l;
  82. {
  83.    register int i;
  84.  
  85.    dest[i = 11] = ' ';
  86.    do dest[--i] = ((char)l & 7) | '0'; while (i>0 && (l>>=3)!=0);
  87.    while (i>0) dest[--i] = ' ';
  88. }
  89.  
  90. void procts(dest, s, suffix)
  91. char dest[]; short s; char suffix;
  92. {
  93.    register int i;
  94.  
  95.    dest[7] = 0;
  96.    dest[i = 6] = suffix;
  97.    do dest[--i] = (s & 7) | '0'; while (i>0 && (s>>=3)!=0);
  98.    while (i>0) dest[--i] = ' ';
  99. }
  100.  
  101. void prcsum(h)
  102. register header *h;
  103. {
  104.    register i;
  105.    /* for the sake of compatibility */
  106.    for (i=0; i<8; i++) (h->m.chksum)[i] = ' ';
  107.    procts(h->m.chksum, headsum(h), 0);
  108. }
  109.  
  110. void newhead(filename, filesize)
  111. char *filename;
  112. long filesize;
  113. {
  114.    nullblock(hblock = steptape());
  115.    procts(hblock->m.mode,  (short)st.st_mode & 07777, ' ');
  116.    procts(hblock->m.uid,   (short)st.st_uid, ' ');
  117.    procts(hblock->m.gid,   (short)st.st_gid, ' ');
  118.    proctl(hblock->m.size,  filesize);
  119.    proctl(hblock->m.mtime, st.st_mtime);
  120.    (void)strncpy(hblock->m.name, filename, MAXTNAME);
  121. }
  122.  
  123. char *deleft(p)
  124. register char *p;
  125. {
  126. #ifdef MSDOS
  127.    if (deldrv && p[1] == ':' &&
  128.                 (p[0]>='A' && p[0]<='Z' || p[0]>='a' && p[0]<='z'))
  129.       p += 2;
  130. #endif
  131.    if (dslash && *p == '/') ++p;
  132.    return p;
  133. }
  134.  
  135. void store(fname)
  136. char *fname;
  137. {
  138.    register i; register j;
  139.    register unsigned m;
  140.    static level = 0;
  141. #ifdef UNIX
  142.    register char *p;
  143. #  ifdef STDDIR
  144.       register DIR *d0; register DIRENT *dp;
  145. #  else
  146.       register char *q; struct direct d_buf; int infile;
  147. #  endif
  148. #endif
  149.  
  150. #ifdef MSDOS
  151.    register k;
  152.    struct ffblk ff;
  153. #endif
  154.  
  155.    if (cbreak) done(EXIT); ++level;
  156.  
  157.    if (strlen(fname) > MAXTNAME) {
  158.       (void)fprintf(myout, longname, fname, "\n");
  159.       goto end;
  160.    }
  161. #ifdef MSDOS
  162.    i = FALSE;
  163.    for (j=strlen(fname); j>0 && fname[j-1]!='/' && fname[j-1]!=':'; j--) {
  164.       if (fname[j-1]=='?' || fname[j-1]=='*') i = TRUE;
  165.    }
  166.  
  167.    if (i) {
  168.       k = findfirst(fname, &ff, filemask);
  169.       while (k==0 && dotname(ff.ff_name)) k = findnext(&ff);
  170.       if (k) {
  171.          if (level < 2) (void)fprintf(myout,"Tar: can\'t find \'%s\'\n",fname);
  172.          goto end;
  173.       }
  174.       do {
  175.          takename(fname+j, ff.ff_name);
  176.          store(fname);
  177.       } while (findnext(&ff) == 0);
  178.       goto end;
  179.    }
  180. #endif
  181.    for (i=0; i<xcnt; i++) {
  182.       if (fmatch(xarg[i], fname)) goto end;
  183.    }
  184.    if (stat(fname, &st) < 0) {
  185.       (void)fprintf(myout, "Tar: can\'t handle \'%s\'\n", fname);
  186.       goto end;
  187.    }
  188.    if ((m = st.st_mode & S_IFMT) == S_IFDIR) {
  189.       if (nonest && level > 1) goto end;
  190.  
  191. #ifdef UNIX
  192.       if (p_flag) {/* save directory & permissions */
  193.          newhead((p = deleft(fname)), 0L);
  194.          if ((j = strlen(p)) < MAXTNAME-1) {
  195.             hblock->m.name[j+1] = '\0';
  196.          } else {
  197.             j = MAXTNAME-1;
  198.          }
  199.          hblock->m.name[j] = '/';
  200.          prcsum(hblock);
  201.       }
  202. #  ifdef STDDIR
  203.       if ((d0 = opendir(fname)) == NULL) {
  204.          (void)fprintf(myout, "Tar: can\'t open directory \'%s\'\n", fname);
  205.          goto end;
  206.       }
  207.       fname[i = strlen(fname)] = '/'; *(p = ++i + fname) = 0;
  208.  
  209.       for (dp=readdir(d0); dp; dp=readdir(d0)) {
  210.      j = namelen(dp);
  211.          if (j==0 ||
  212.             (j==1 && (dp->d_name)[0]=='.') ||
  213.             (j==2 && (dp->d_name)[0]=='.' && (dp->d_name[1])=='.'))
  214.             continue;
  215.          for (i=0; i<j; i++) p[i] = (dp->d_name)[i];
  216.          p[j] = 0;
  217.          store(fname);
  218.       }
  219.       closedir(d0);
  220. #  else
  221.       if ((infile = open(fname, O_RDONLY)) < 0) {
  222.          (void)fprintf(myout, "Tar: can\'t open file \'%s\'\n", fname);
  223.          goto end;
  224.       }
  225.       fname[i = strlen(fname)] = '/'; *(p = ++i + fname) = 0;
  226.  
  227.       i = 0;
  228.       while (read(infile, (char*)&d_buf, sizeof(d_buf)) > 0 && !cbreak) {
  229.          if (d_buf.d_ino!=0 && !dotname(d_buf.d_name)) {
  230.             q = p;
  231.             for (j=0; j<DIRSIZ; j++) *q++ = d_buf.d_name[j];
  232.             *q = '\0';
  233.             (void)close(infile); /* need this file handler */
  234.             store(fname);
  235.             *p = '\0';
  236.             infile = open(fname, O_RDONLY);
  237.             (void)lseek(infile, (long)(sizeof(d_buf) * (i+1)), 0);
  238.          }
  239.          ++i;
  240.       }
  241. #  endif
  242.       if (y_flag) {
  243. #        ifdef RMKDIR
  244.             if (rmdir(fname) != 0) {
  245.                (void)fprintf(myout, "Tar: can\'t remove \'%s\'\n", fname);
  246.             }
  247. #        else
  248.             if (bincall("rmdir", fname) == -1) {
  249.                (void)fprintf(myout, "Tar: fault run rmdir!\n");
  250.             }
  251. #        endif
  252.       }
  253. #endif
  254. #ifdef MSDOS
  255.       j = strlen(fname);
  256.       strcpy(fname+j, "/*.*");
  257.  
  258.       store(fname);
  259.  
  260.       if (y_flag) {
  261.          fname[j] = 0;
  262.          if (rmdir(fname) != 0) {
  263.             (void)fprintf(myout, "Tar: can\'t remove \'%s\'\n", fname);
  264.          }
  265.       }
  266. #endif
  267.    } else if (m == S_IFREG) {
  268.       savefile(fname);
  269.    } else {
  270. #ifdef UNIX
  271.       p = deleft(fname);
  272.       if (w_flag && !okwork('a', ' ', &st, fname)) goto end;
  273.       if (v_flag) (void)fprintf(myout, "a %s\n", p);
  274.       if (m == S_IFCHR || m == S_IFBLK || m == S_IFIFO) {
  275.          newhead(p, 0L);
  276.          if (m == S_IFIFO) {
  277.             hblock->m.filetype = TF_QUE;
  278.          } else {
  279.             hblock->m.filetype = m == S_IFBLK ? TF_BLK : TF_CHR;
  280.             procts(hblock->x.devmajor, major(st.st_rdev), ' ');
  281.             procts(hblock->x.devminor, minor(st.st_rdev), ' ');
  282.          }
  283.          prcsum(hblock);
  284.       } else
  285. #endif
  286.          (void)fprintf(myout, "Tar: \'%s\' not a file\n", fname);
  287.    }
  288. end: --level;
  289. }
  290.